#include "types.h"
#include "spinlock.h"

// push_off/pop_off are like intr_off()/intr_on() but they are matched:
// it takes two pop_off()s to undo two push_off()s.  Also, if interrupts
// are initially off, then push_off, pop_off leaves them off.
void
push_off(void)
{
  // 在RISC-V中，我们需要保存sstatus寄存器的SIE位
  // 这里简化为关闭中断
  asm volatile("csrw sie, zero");
}

void
pop_off(void)
{
  // 简化为开启中断
  asm volatile("csrw sie, %0" : : "r" (1 << 1));
}

// acquire a lock.
// Loops (spins) until the lock is acquired.
void
acquire(struct spinlock *lk)
{
  push_off(); // disable interrupts to avoid deadlock.
  if(lk->locked)
    // 在单核环境中，如果锁被持有，则系统无法继续，这是一个简化的占位符
    // 在多核中，这里会自旋
    while(lk->locked);

  // Tell the C compiler and the processor to not move loads or stores
  // past this point, to ensure that the critical section's memory
  // references happen after the lock is acquired.
  __sync_synchronize();

  // Record info about lock acquisition for holding() and debugging.
  lk->locked = 1;
}

// Release the lock.
void
release(struct spinlock *lk)
{
  // Tell the C compiler and the processor to not move loads or stores
  // past this point, to ensure that all stores in the critical section
  // are visible to other cores before the lock is released.
  __sync_synchronize();

  // Release the lock.
  lk->locked = 0;

  pop_off();
}
